<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowd');

class Crud {

    private $controller = '';
    private $header = '';
    private $CI = '';
    private $default_limit = 5;
    private $offset = 0;
    private $sorted = 'id';
    private $order = 'ASC';
    private $user_id = 0;

    function __construct($par=array()) {
        if ($par && count($par) > 0) {
            $this->initialize($par);
        }

        $this->CI = & get_instance();
        $this->user_id = $this->CI->u->id;

        if (!isset($GLOBALS['table'][$this->controller])) {
            $this->init_global();
        }

        if (!isset($GLOBALS['headers'][$this->controller])) {
            $this->init_global('header');
        }

        $this->header = $GLOBALS['headers'][$this->controller];
    }

    function initialize($par) {
        foreach ($par as $i => $v) {
            $this->$i = $v;
        }
    }

    function init_param($index, $values) {
        $this->$index = (is_array($values)) ? array_merge($this->$index, $values) : array_merge($this->$index, array($values));
    }

    function get($index) {
        return $this->$index;
    }

    function init_global($type='form') {
        $res = $this->CI->db->query('describe ' . $this->controller);
        foreach ($res->result_array() as $i => $v) {
            $index = $v['Field'];
            if ($type == 'form') {
                $GLOBALS['table'][$this->controller][$index]['label'] = ucwords($index);
            } elseif ($type == 'header') {
                $GLOBALS['headers'][$this->controller][$index] = ucwords($index);
            }
        }
    }

    function save($param) {

        extract($param);

        $ret = false;

        if (isset($where)) {
            $this->CI->db->where($where);
            $this->CI->db->update($this->controller, $data);
            $ret = 'modify';
        } else {

            if (!in_array($this->controller, array('users'))) {
                $data = array_merge($data, array('user' => $this->user_id));
            }

            $this->CI->db->insert($this->controller, $data);
            $ret = $this->CI->qb->get_last_id($this->controller);
        }

        return $ret;
    }

    function c_save($id=0, $ajax=false) {

        $param = array();
        $action = 'save';
        $label = 'Added';
        if ($id) {
            $param['where'] = array('id' => $id);
            $action = 'modify';
            $label = 'Modified';
        }

        $message = (isset($GLOBALS['messages'][$this->controller][$action])) ? $GLOBALS['messages'][$this->controller][$action] : 'Data ' . $label;

        $this->CI->session->set_userdata(array('alerts' => array('message' => $message, 'type' => 'info')));

        $form_attributes = $GLOBALS['table'][$this->controller];

        foreach ($form_attributes as $i => $v) {

            if (!in_array($this->controller . ':' . $i, array('files:location'))) {
                $param['data'][$i] = $this->change_input($i);
                //$param['data'][$i] = $this->CI->input->post($i);
            }
        }

        
        $res = $this->save($param);
        
        $this->additional_data($param['data'],$id,$res);
        
        if ($res && !$ajax) {
            header('Location: ' . BASE_URL . $this->controller . '/index/list/');
            exit();
        }
    }

    function change_input($index) {
        $ret = $this->CI->input->post($index);
        switch ($this->controller . ':' . $index) {
            case'pages:content':
                $ret = str_replace(
                        array("\n", "\r", "<p>", "</p>", "&nbsp;"), array('', '', '', '<br />', ''), $ret
                );
                $ret = preg_replace("/>\s+</", '><', $ret);
                break;
            default :
                break;
        }

        return $ret;
    }

    function additional_data($data, $id, $res) {
        $id = (is_numeric($res))?$res:$id;
        $param = array();
        $param['where'] = array('id' => $id);
        switch ($this->controller) {
            case 'banners':
                $width = $data['width'];
                $height = $data['height'];
                $hash = md5($id);
                $param['data']['hash'] = $hash;
                $param['data']['code'] = '<div id="banner" class="' . $hash . '" style="width: ' . $width . 'px; height: ' . $height . 'px;"></div><script type="text/javascript" src="' . BASE_URL . 'init-banner.js"></script>';
                
                $res = $this->save($param);
                break;
            case 'pages':
                $param['data']['url'] = 'pages/current/' . $id;
                $res = $this->save($param);
                break;
            default :
                break;
        }
    }

    function add_edit($param) {

        extract($param);

        $default = array('method' => 'post', 'enctype' => 'multipart/form-data', 'class' => 'validate');

        $form_attributes = $GLOBALS['table'][$this->controller];

        if (isset($edit) && $edit) {
            init_values($form_attributes, $values);
        }

        collect_inputs($form_attributes);

        $param_view = array(
            'data' => $form_attributes,
            'action' => $action,
            'attributes' => (isset($attributes)) ? array_merge($default, $attributes) : $default,
            'hidden' => (isset($hidden)) ? $hidden : '',
        );


        return $this->CI->load->view('crud/add_edit', $param_view, true);
    }

    //====================================================================================

    function c_listing($page=0) {

        $limit = '';

        $this->set_limit($limit, $page);

        $paging = $this->paging(array('page' => $page, 'limit' => $limit));

        $param = array(
            'from' => $this->controller,
            'order_by' => $this->get_sort(),
            'limit' => array($limit, $this->offset)
        );

        if (!in_array($this->controller, array('users'))) {
            $param['where'] = array('user' => $this->user_id);
        } else {
            $param['where'] = array('id' => $this->user_id);
        }



        $res = $this->CI->qb->select($param);

        $param = array(
            'data' => $res,
            'header' => $this->header,
            'controller' => $this->controller,
            'paging' => $paging,
            'order' => array($this->sorted => $this->order)
        );

        return $this->CI->load->view('crud/list', $param, TRUE);
    }

    function set_limit(&$limit, &$page) {
        $limit = $this->CI->input->post('limit');

        if ($limit) {

            $page = $this->CI->input->post('page_option');
            $page++;
            $this->CI->session->set_userdata(array('limit' => $limit));
        }

        $limit = $this->CI->session->userdata('limit');

        if (!$limit) {
            $limit = $this->default_limit;
        }
    }

    function set_sort($param) {
        extract($param);
        $set = array(
            $this->controller => array('order_by' => array($field => $order), 'sorted' => $field)
        );
        $this->CI->session->set_userdata($set);
    }

    function get_sort() {
        $res = $this->CI->session->userdata($this->controller);
        if (isset($res['order_by'])) {
            foreach ($res['order_by'] as $i => $v) {
                $this->sorted = $i;
                $this->order = $v;
            }
        }
        return array($this->sorted => $this->order);
    }

    function paging($vars) {

        if ($vars['page'] > 0) {
            $vars['page'] -= 1;
        }

        $param = array(
            'query' => array('from' => $this->controller),
            'page' => $vars['page'],
            'limit' => $vars['limit'],
            'order' => 'ASC',
            'action' => 'list',
            'status' => 'active'
        );

        $this->CI->pg->set_param($param);

        $param = array('controller' => $this->controller);
        $param = array_merge($param, $this->CI->pg->result_array());
        $this->offset = $param['offset'];

        return $this->CI->load->view('crud/paging', $param, true);
    }

    function c_add() {
        $param = array(
            'action' => $this->controller . '/index/save'
        );
        return $this->add_edit($param);
    }

    function c_edit($id=0) {
        $param = array(
            'from' => $this->controller,
            'where' => array('id' => $id),
            'limit' => 1
        );
        $res = $this->CI->qb->select($param);

        $hidden = array('id' => $id);

        $param = array(
            'action' => $this->controller . '/index/save/1',
            'edit' => true,
            'hidden' => $hidden
        );

        if ($res->num_rows > 0) {

            $values = $res->row_array();
            $param['values'] = $values;
            return $this->add_edit($param);
        } else {
            return 'not found!';
        }
    }

}

